package com.andreas.service.impl;

import com.andreas.dao.MenuMapper;
import com.andreas.domain.Menu;
import com.andreas.dto.MenuDTO;
import com.andreas.service.MenuService;
import com.andreas.vo.MenuVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 描述：MenuServiceImpl实现类
 */
@Service
public class MenuServiceImpl implements MenuService {
    @Autowired
    private MenuMapper menuMapper;

    /**
     * @Author: andreaszhou
     * @Description: 查看所有的父子菜单信息
     * @DateTime: 2021/7/25 19:26
     * @Params:
     * @Return
     */
    @Override
    public List<MenuVO> findSubMenuListByPid(int id) {
        List<Menu> subMenuList = menuMapper.findSubMenuListByPid(id);
        // 在此处需要写递归将subMenuList赋值给VO
        List<MenuVO> menuVOS = new ArrayList<>();
        for (Iterator<Menu> iterator = subMenuList.iterator(); iterator.hasNext(); ) {
            Menu menu = iterator.next();
            MenuVO menuVO = new MenuVO();
            BeanUtils.copyProperties(menu, menuVO); // copyProperties属性的值都会copy过去的，所有的属性都会copy过去的。
            menuVOS.add(menuVO);
        }
        return menuVOS;
    }

    /**
     * 功能描述 树形结构返回菜单信息
     *
     * @param id
     * @return
     * @author qian.zhou
     * @date 2021/9/9
     */
    public List<MenuVO> findSubMenuListByPidAndRecursion(Integer id) {
        // 查找对应的所有的menu菜单信息
        List<Menu> allMenu = menuMapper.findAllMenu();
        List<MenuVO> allMenuVO = new ArrayList<>();
        for (Menu m : allMenu
        ) {
            MenuVO menuVO = new MenuVO();
            BeanUtils.copyProperties(m, menuVO);
            allMenuVO.add(menuVO);
        }
        return buildMenuTreeSelect(allMenuVO);
    }

    /**
     * 功能描述 构建前端所需要的下拉树结构
     *
     * @param allMenuVO
     * @return java.util.List<com.andreas.vo.MenuVO>
     * @author qian.zhou
     * @date 2021/9/9
     */

    private List<MenuVO> buildMenuTreeSelect(List<MenuVO> allMenuVO) {
        return buildMenuTree(allMenuVO);
    }

    /**
     * 功能描述 构建前端所需要的结构
     *
     * @param allMenuVO
     * @return java.util.List<com.andreas.vo.MenuVO>
     * @author qian.zhou
     * @date 2021/9/9
     */

    private List<MenuVO> buildMenuTree(List<MenuVO> allMenuVO) {
        // 1.新建返回结果returnList 和 tempList
        List<MenuVO> menuVOS = new ArrayList<>();
        List<Integer> tempList = new ArrayList<>();
        for (MenuVO vo : allMenuVO
        ) {
            tempList.add(vo.getId());
        }
        for (Iterator<MenuVO> iterator = allMenuVO.iterator(); iterator.hasNext(); ) {
            MenuVO nextVO = iterator.next();
            if (!tempList.contains(nextVO.getParentId())) {
                recursionFn(allMenuVO, nextVO);
                menuVOS.add(nextVO);
            }
        }
        if (menuVOS.isEmpty()) {
            menuVOS = allMenuVO;
        }
        return menuVOS;
    }

    /**
     * 功能描述 递归列表
     *
     * @param allMenuVO
     * @param nextVO
     * @return void
     * @author qian.zhou
     * @date 2021/9/9
     */

    private void recursionFn(List<MenuVO> allMenuVO, MenuVO nextVO) {
        // 得到子节点列表
        List<MenuVO> childList = getChildList(allMenuVO, nextVO);
        nextVO.setSubMenuList(childList);
        for (MenuVO m : childList
        ) {
            if (hasChild(allMenuVO, m)) {
                recursionFn(allMenuVO, m);
            }
        }
    }

    /**
     * 功能描述 判断是否有子节点存在
     *
     * @param allMenuVO
     * @param m
     * @return boolean
     * @author qian.zhou
     * @date 2021/9/9
     */

    private boolean hasChild(List<MenuVO> allMenuVO, MenuVO m) {
        return getChildList(allMenuVO, m).size() > 0 ? true : false;
    }

    /**
     * 功能描述 得到子节点列表，如果子节点列表存在，那么返回对应的子节点的列表，如果子节点列表不存在，那么返回null
     *
     * @param allMenuVO
     * @param nextVO
     * @return java.util.List<com.andreas.vo.MenuVO>
     * @author qian.zhou
     * @date 2021/9/9
     */

    private List<MenuVO> getChildList(List<MenuVO> allMenuVO, MenuVO nextVO) {
        List<MenuVO> subMenuVO = new ArrayList<>();
        Iterator<MenuVO> iterator = allMenuVO.iterator();
        while (iterator.hasNext()) {
            MenuVO vo = iterator.next();
            if (vo.getParentId().intValue() == nextVO.getId().intValue()) {
                subMenuVO.add(vo);
            }
        }
        return subMenuVO; // 如果没有子菜单的值，那么返回的是一个null的值
    }


    /**
     * @Author: andreaszhou
     * @Description: 查询菜单列表
     * @DateTime: 2021/7/26 21:42
     * @Params:
     * @Return
     */
    @Override
    public Map<Object, Object> findAllMenu(Integer currentPage, Integer pageSize) {
        if (currentPage != null && pageSize != null) {
            PageHelper.startPage(currentPage, pageSize);
        }
        List<MenuVO> menuVOList = new ArrayList<>();
        List<Menu> menuList = menuMapper.findAllMenu();
        for (Menu m : menuList
        ) {
            MenuVO menuVO = new MenuVO();
            BeanUtils.copyProperties(m, menuVO);
            menuVOList.add(menuVO);
        }
        // 定义Map进行返回数据的封装
        Map<Object, Object> map = new HashMap<>();
        // 获取返回菜单数据的数量
        Integer total = menuMapper.getMenuNum();
        map.put("total", total);
        map.put("menus", menuVOList);
        return map;
    }

    /**
     * @Author: andreaszhou
     * @Description: 修改菜单
     * @DateTime: 2021/7/26 22:11
     * @Params:
     * @Return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateMenu(MenuDTO dto) {
        Menu menu = new Menu();
        BeanUtils.copyProperties(dto, menu);
        Date date = new Date();
        menu.setUpdatedBy("system");
        menu.setUpdatedTime(date);
        return menuMapper.updateMenu(menu);
    }

    /**
     * @Author: andreaszhou
     * @Description: 保存菜单
     * @DateTime: 2021/7/26 22:11
     * @Params:
     * @Return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveMenu(MenuDTO dto) {
        Menu menu = new Menu();
        BeanUtils.copyProperties(dto, menu);
        Date date = new Date();
        menu.setCreatedTime(date);
        menu.setUpdatedTime(date);
        menu.setCreatedBy("system");
        menu.setUpdatedBy("system");
        return menuMapper.saveMenu(menu);
    }

    /**
     * @Author: andreaszhou
     * @Description: 菜单层级，从0开始, 保存信息的时候和修改信息的时候需要对应的层级修改
     * @DateTime: 2021/7/31 21:00
     * @Params:
     * @Return
     */
//    public Integer level(){
//
//    }

    /**
     * @Author: andreaszhou
     * @Description: 根据id查找对应的Menu信息
     * @DateTime: 2021/7/27 12:36
     * @Params:
     * @Return
     */
    @Override
    public Menu findMenuById(Integer id) {
        return menuMapper.findMenuById(id);
    }

    /**
     * @Author: andreaszhou
     * @Description: 删除菜单信息
     * @DateTime: 2021/7/29 22:45
     * @Params:
     * @Return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteMenu(Integer id) {
        return menuMapper.deleteMenu(id);
    }
    /**
     *功能描述 判断当前菜单下面是否有子菜单
     * @author qian.zhou
     * @date 2021/9/15
     * @param id
     * @return java.lang.Integer
     */

    @Override
    public Integer isSubMenu(Integer id) {
        return menuMapper.isSubMenu(id);
    }
}
